package com.tmpt.wf;

import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.zip.ZipInputStream;

/**
 * Created by wxy on 2017/10/2.
 */
@Slf4j
@Service(value="wfDemo")
public class WfDemo {

    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private HistoryService historyService;

    String assignee = "张三";
    String processInstanceId = "70001";

    public void test2(){
        // 部署流程
        //String deploymentId = deploy();
        //findProcessDefinition();

        // 开启流程，myprocess是流程的ID
        //startProcess("myProcess");
        //deleteDeployment(deploymentId);

        /*try {
            viewImange(deploymentId);
        } catch (IOException e) {
            e.printStackTrace();
        }*/
/*

        queryMyTask(assignee);
        //setVariables();
        //getVariables();
        //findHistoryTask(assignee);
        String taskId = "70004";
        completeTask(taskId);
        queryMyTask(assignee);
*/

        boolean isProcessEnd = isProcessEnd(processInstanceId);
        //.out.println("isProcessEnd:"+isProcessEnd);

        /*
        // 查询历史表中的Task
        List<Task> task = taskService.createTaskQuery().list();
        //.out.println("============"+task.size());
        Task task1 = task.get(task.size()-1);
        sb.append("第一环节："+task1 +"<br/>");
        sb.append("推动流程到下一环节："+task1+"<br/>");
        taskService.complete(task1.getId());
        task1 = taskService.createTaskQuery().executionId(task1.getExecutionId()).singleResult();
        sb.append("第二环节：" + task1+"<br/>");*/
    }

    public String deploy(){
        // 部署流程，只要是符合BPMN2规范的XML文件，理论上都可以被ACTIVITI部署
        Deployment deployment = repositoryService
                .createDeployment()
                .name("我的第一次")
                .addClasspathResource("diagrams/MyProcess.bpmn")
                .addClasspathResource("diagrams/MyProcess.png").deploy();
        //.out.println("====>depId:" + deployment.getId() + "   depName:" + deployment.getName());
        return deployment.getId();
    }
    public String deploy_inputstream(){
        // 部署流程，只要是符合BPMN2规范的XML文件，理论上都可以被ACTIVITI部署
        InputStream in = getClass().getClassLoader()
                .getResourceAsStream("diagrams/MyProcess.bpmn");
        InputStream inPng = getClass().getClassLoader()
                .getResourceAsStream("diagrams/MyProcess.png");
        Deployment deployment = repositoryService
                .createDeployment()
                .name("我的第一次")
                .addInputStream("MyProcess.bpmn",in)
                .addInputStream("MyProcess.png", inPng)
                .deploy();
        //.out.println("====>depId:" + deployment.getId() + "   depName:" + deployment.getName());


        //从classpath根目录下加载文件
        getClass().getClassLoader().getResourceAsStream("diagrams/MyProcess.bpmn");
        //从classpath根目录下加载文件
        getClass().getResourceAsStream("/MyProcess.bpmn");
        //从当前包下加载指定名称的文件
        getClass().getResourceAsStream("MyProcess.bpmn");

        return deployment.getId();
    }
    public void deployZip(){
        // 部署流程，只要是符合BPMN2规范的XML文件，理论上都可以被ACTIVITI部署
        InputStream in = getClass().getClassLoader()
                .getResourceAsStream("diagrams/MyProcess.zip");
        ZipInputStream zipInputStream = new ZipInputStream(in);
        Deployment deployment = repositoryService.createDeployment()
                .name("我的第一次")
                .addZipInputStream(zipInputStream)
                .deploy();
        //.out.println("====>depId:" + deployment.getId() + "   depName:" + deployment.getName());
    }

    /**
     * 开启流程，myprocess是流程的ID
     */
    public void startProcess(String key){
        // 开启流程，myprocess是流程的ID
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key);
        //.out.println("====>processInstanceId:"+processInstance.getId()+"   ActivityId:"+processInstance.getActivityId());
    }

    public boolean isProcessEnd(String processInstanceId){
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
        if(processInstance == null){
            return true;
        }else{
            //.out.println("当前流程在："+processInstance.getActivityId());
            return false;
        }


    }

    public void queryMyTask(String assignee){
        System.out.print("====>queryMyTask:" + assignee);
        List<Task> taskList = taskService
                .createTaskQuery()
                .taskCandidateOrAssigned(assignee).list();
                //.taskAssignee(assignee).list();
        for(Task task : taskList){
            System.out.print("====>");//taskId:90010,taskName:外勤队员
            //.out.println("taskId:" + task.getId() + ",taskName:" + task.getName() + " ");

            String piId = task.getProcessInstanceId();
            ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(piId).singleResult();
            //.out.println("====:"+pi.getBusinessKey());
        }
    }

    public void assignToAnother(String taskId, String userIds){
        taskService.setAssignee(taskId, userIds);
    }

    public void setVariables(){
        Task task = taskService.createTaskQuery()
                .taskAssignee(assignee)
                .processInstanceId(processInstanceId)
                .singleResult();
        taskService.setVariable(task.getId(), "message", "重要");
    }

    public void getVariables(){
        Task task = taskService.createTaskQuery()
                .taskAssignee(assignee)
                .processInstanceId(processInstanceId)
                .singleResult();
        String message = (String)taskService.getVariable(task.getId(), "message");
        //.out.println("=======>message:" + message);
    }

    public void findHistoryTask(String assignee){
        System.out.print("====>findHistoryTask:" + assignee);
        List<HistoricTaskInstance> hisTaskList = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(assignee).list();
        for(HistoricTaskInstance hisTask : hisTaskList){
            System.out.print("====>");
            //.out.println("hisTaskId:"+hisTask.getId()+",hisTaskName:"+hisTask.getName());
        }
    }



    public void completeTask(String taskId){
        taskService.complete(taskId);
        //.out.println("taskId:" + taskId + ",完成任务");
        //queryMyTask();
    }

    /**
     * 查看流程定义
     */
    public void findProcessDefinition(){
        List<ProcessDefinition> list = repositoryService
                .createProcessDefinitionQuery()
                .orderByProcessDefinitionVersion()
                .asc()
                .list();
        for(ProcessDefinition processDefinition:list){
            //.out.println("ID:"+processDefinition.getId());
            //.out.println("Name:"+processDefinition.getName());
            //.out.println("Key:"+processDefinition.getKey());
        }
    }

    /**
     * 删除流程定义
     */
    public void deleteDeployment(String deploymentId){
        repositoryService.deleteDeployment(deploymentId,false);
    }

    public void viewImange(String deploymentId) throws IOException {
        List<String> nameList = repositoryService.getDeploymentResourceNames(deploymentId);
        String imageName = null;
        for(String name:nameList){
            //.out.println("=====>"+name);
            if(name.indexOf(".png")>=0){
                imageName = name;
            }
        }
        if(imageName!=null){
            File file = new File("e:/"+imageName);
            InputStream in = getClass().getClassLoader()
                    .getResourceAsStream(imageName);
            FileCopyUtils.copy(in, new FileOutputStream(file));
        }
    }

    public void addGroupUser(String taskId, String userId){
        taskService.addCandidateUser(taskId,userId);
    }

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring-contextjta.xml"});
        WfDemo wfDemo = (WfDemo)context.getBean("wfDemo");
        //wfDemo.deployTask();
        /*wfDemo.assignToAnother("90010",null);
        wfDemo.addGroupUser("90010","2");
        //.out.println("=====>userId:2");
        wfDemo.queryMyTask("2");*/
       /* //.out.println("=====>userId:11");
        wfDemo.queryMyTask("11");
        //.out.println("=====>userId:10,11");
        wfDemo.queryMyTask("10,11");*/
    }


    public String deployTask(){
        // 部署流程，只要是符合BPMN2规范的XML文件，理论上都可以被ACTIVITI部署
        Deployment deployment = repositoryService
                .createDeployment()
                .name("出勤任务")
                .addClasspathResource("diagrams/Task.bpmn")
                .addClasspathResource("diagrams/Task.png").deploy();
        //.out.println("====>depId:" + deployment.getId() + "   depName:" + deployment.getName());
        return deployment.getId();//depId:82501   depName:出勤任务
    }

    /*public void startLeave() {
        Map<String, Object> variables = Maps.newHashMap();
        variables.put("applyuserid", "123456789");
        ProcessInstance leaveProcess = runtimeService.startProcessInstanceByKey("leaveProcess");
        log.info("myProcess name:{},ProcessDefinitionId:{},BusinessKey:{},DeploymentId:{},ProcessDefinitionKey:{},ProcessVariables:{}"
                , leaveProcess.getName(), leaveProcess.getProcessDefinitionId(),
                leaveProcess.getBusinessKey(), leaveProcess.getDeploymentId(),
                leaveProcess.getProcessDefinitionKey(), leaveProcess.getProcessVariables());
    }*/


}
